#include "bsp_buzzer.h"
#include "systick.h"

// 蜂鸣器初始化
void BUZZER_GPIO_Config(void) 
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 使能蜂鸣器端口时钟
    RCC_APB2PeriphClockCmd(BUZZER_GPIO_CLK, ENABLE);
    
    // 配置蜂鸣器引脚为推挽输出
    GPIO_InitStructure.GPIO_Pin = BUZZER_GPIO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(BUZZER_GPIO_PORT, &GPIO_InitStructure);
}

// 设定初始状态为关闭
void BUZZER_InitState(void)
{
	BUZZER_OFF;
}

// 固定周期输出，占空比D%（0~100），持续time_ms毫秒
void BUZZER_OutputDuty(uint8_t duty_percent, uint32_t duration_ms)
{
	if(duty_percent > 100) duty_percent = 100;    // 边界处理：占空比超过100时强制设为100

	// 计算高电平/低电平时长（微秒）
	uint32_t period_us = BUZZER_PWM_PERIOD_US; // 例如 1000us -> 1kHz
	uint32_t on_us = (period_us * duty_percent) / 100;   // 高电平时长 = 周期 × 占空比/100
	uint32_t off_us = period_us - on_us;                 // 低电平时长 = 周期 - 高电平时长

	// 若占空比为0或100，直接保持常灭/常亮
	if(duty_percent == 0) {
		BUZZER_OFF;
		SysTick_Delay_Nms(duration_ms);
		return;
	}
	// 占空比100% → 持续开启，结束后关闭
	if(duty_percent == 100) {
		BUZZER_ON;
		SysTick_Delay_Nms(duration_ms);
		BUZZER_OFF;
		return;
	}

	// 需要循环输出固定周期，直到达到持续时长
	uint32_t elapsed_ms = 0;
	while(elapsed_ms < duration_ms) {
		// 一个周期：先ON再OFF
		BUZZER_ON;
		if(on_us >= 1000) {
			SysTick_Delay_Nms(on_us / 1000);
		} else if(on_us > 0) {
			SysTick_Delay_Nus(on_us);
		}

		BUZZER_OFF;
		// 高电平时长≥1ms → 用毫秒延时
		if(off_us >= 1000) {
			SysTick_Delay_Nms(off_us / 1000);
		}
		// 高电平时长<1ms → 用微秒延时
		else if(off_us > 0) {
			SysTick_Delay_Nus(off_us);
		}

		// 累计整周期的毫秒数
		elapsed_ms += (period_us + 999) / 1000;
	}

	BUZZER_OFF;
}

// 非阻塞蜂鸣器脉冲：调用一次开始鸣叫，持续on_ms后自动关闭。
// 需在while(1)循环内连续调用此函数以维持计时。
void BUZZER_Task_Pulse(uint32_t on_ms)
{
	static uint8_t active = 0;              // 静态变量：记录蜂鸣器是否处于活跃状态
	static uint32_t start_ms = 0;           // 静态变量：记录脉冲启动时的系统毫秒数，用于计算已持续时间
	uint32_t now = SysTick_Millis();        // 获取当前系统运行的总毫秒数

	if(on_ms == 0)
	{
		// 若当前处于活跃状态
		if(active)
		{
			BUZZER_OFF;
			active = 0;                      // 重置活跃状态
		}
		return;
	}
    // 请求启动脉冲，且当前未活跃
	if(!active)
	{
	
		BUZZER_ON;
		start_ms = now;                  // 记录启动时间
		active = 1;                      // 标记为活跃状态
	}
	else
	{
		if(now - start_ms >= on_ms)      // 若当前时间 - 启动时间 ≥ 设定持续时间 → 脉冲结束
		{
			BUZZER_OFF;
			active = 0;
		}
	}
}

// 非阻塞PWM：固定500Hz（周期2ms），以毫秒时基近似PWM，占空比0~100。


// 非阻塞周期鸣叫：on_ms鸣叫，off_ms静音，循环往复
void BUZZER_Task_Beep(uint32_t on_ms, uint32_t off_ms, uint8_t enable)
{
	static uint8_t state = 0; // 0:静音期, 1:鸣叫期
	static uint32_t phase_start = 0;
	uint32_t now = SysTick_Millis();

	if(!enable)
	{
		BUZZER_OFF;
		state = 0;
		phase_start = now;
		return;
	}

	// 边界：允许某一段为0ms
	if(state == 0)
	{
		// 静音期，检查是否进入鸣叫期
		if(off_ms == 0 || now - phase_start >= off_ms) {
			// 进入鸣叫期
			phase_start = now;
			state = 1;
		}
		BUZZER_OFF;
	}
	else
	{
		// 鸣叫期：对有源蜂鸣器，直接拉高即可发声
		BUZZER_ON;
		if(on_ms == 0 || now - phase_start >= on_ms) {
			// 切回静音期
			phase_start = now;
			state = 0;
			BUZZER_OFF;
		}
	}
}
